package anshe.widget
{
	import anshe.event.AnsheKeyword;
	import anshe.event.AnsheNetEvent;
	import anshe.net.AnsheNet;
	import anshe.net.RedConnection;
	import anshe.net.RedSharedObject;
	import anshe.struct.ActionStruct;
	import anshe.struct.SWFData;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.ByteArray;

	public dynamic class AnsheNetSpace extends Sprite
	{
		private var myNC:RedConnection;		//	全局NC对象
		private var mySO:RedSharedObject;	//	房间SO对象（全局）
		
		private var gameArray:Array;
			//	需要使用 RedNetConnection 对象的游戏对象列表
			//	该列表中的对象均是 AnsheSuperClient 类对象
		
		private var swfArray:Array;
			//	需要下载的SWF文件的数据。定义该数据后，可防止重复加载的问题。
			//	但为保证唯一性，可以在传入的参数接收完毕后，删除该数据项内容
		
		public function AnsheNetSpace()
		{
			myNC = AnsheNet.nc;
			mySO = AnsheNet.so;
			
			gameArray = new Array(null);
			swfArray = new Array();
			
			this.addEventListener(Event.ADDED_TO_STAGE, InitSpaceData);
		}
		
		public function get nc():RedConnection
		{
			return this.myNC;
		}
		
		//	连接上服务器
		public function connServer(ncPath:String = null, ...argc):void
		{
			if(!myNC.connected)
			{
				if(ncPath)
				{			
					myNC.connect(ncPath);//, argc);
				}
				else
				{
					myNC.connect(AnsheNet.NCURL);//, argc);
				}
			}				
		}
		
		//	连接全局 SharedObject 对象
		public function connGlobalSO(soPath:String = null, ...argc):void
		{
			if(myNC.connected)
			{
				mySO.connect(soPath, myNC);
			}
		}
		
		//	发送消息（传入参数 client 代表消息发送者，actName 为消息号， funcName 为回调函数名，...argc 为参数列表）
		//		isSoMessage 代表回调的函数是否为 SO 上定义的方法
		//		isGlobal 代表要传输的命令是否为 非游戏对象 进行接收（
		public function sendCommand(client:Object, actName:String, funcName:String, isSoMessage:Boolean, isGlobal:Boolean = false, argc:Array = null):void
		{
			// trace("SendCommand :: " + client, actName, funcName, isGlobal, argc);
			
			if(myNC.connected)
			{
				if(!gameArray)
				{
					gameArray = new Array();
				}
				
				var act:ActionStruct = new ActionStruct(gameArray.length);
				act.actClient = client;
				act.actFunction = funcName;
				
				gameArray.push(act);
				
				argc = (argc == null) ? new Array() : argc;
				
				if(!isGlobal)
				{
					if(isSoMessage)
					{
						myNC.call(AnsheNetEvent.SEND_COMMAND, null, client.gameName, actName + "_" + act.id, funcName, argc);
					}
					else
					{
						// trace("SendMessage by " + client.gameName);
						myNC.call(AnsheNetEvent.SEND_COMMAND, null, client.gameName, actName + "_" + act.id, "onNCRecord", argc);
					}
				}
				else
				{
					// trace("SendMessage by null");
					myNC.call(AnsheNetEvent.SEND_COMMAND, null, null, actName + "_" + act.id, "onNCRecord", argc);
				}
			}
		}
		
		//	接收服务器回调的函数，并执行相关的回调操作
		public function onNCRecord(...argc):void
		{
			// try
			// {
				// trace("收到的返回串:", argc);
				
				if((argc as Array).length > 0)
				{
					var actID:Number = Number(argc.shift());
					
					if(this.gameArray.length >= actID)
					{ 
						var act:ActionStruct = this.gameArray[actID];
						if(act)
						{
							if(act.id == actID)
							{
								act.DoFunction(argc);
							}
						}
					}
				}
			//}
			//catch(e:*)
			//{
			//	trace("分析返回串时出错:: " + e);
			//}
		}
		
		//	通知服务器，要开始连接
		public function DownloadSWF(...argc):void
		{
			try
			{
				if(myNC.connected)
				{
					myNC.call(AnsheNetEvent.SEND_COMMAND, null, null, AnsheKeyword.DOWNLOAD_SWF, "onGetSwfData", argc);
				}
				else
				{
					// FDebug.showError("没有连上服务器");
				}
			}
			catch(e:*)
			{
				// FDebug.showError("下载时出错了:",e);
			}
		}
		
		//	取得来自于服务器端的下载数据
		public function onGetSwfData(...argc):void
		{
			// trace(argc);
			try
			{
				var numTotal:Number = Number(argc[1]);
				var numID:Number = Number(argc[2]);
				var dataArray:Array = argc[3];
				var isEndFlag:Boolean = Boolean(argc[4]);
				var swfName:String = String(argc[5]).substring(0, String(argc[5]).indexOf(".swf") + 4);
				
				var objLoad:SWFData = GetSwfData(swfName);
				
				if(objLoad.swfTotal == 0)
				{
					objLoad.swfTotal = numTotal;
				}
				
				// trace("Data::" + argc[0], argc[1], argc[2], argc[3].length, argc[4], argc[5], isEndFlag);
							
				objLoad.push(numID, dataArray);
				
				if(isEndFlag)
				{
					// trace("Send end");
					this.dispatchEvent(new AnsheNetEvent(AnsheNetEvent.LOAD_SWF_DONE, objLoad));
				}
				else
				{
					// trace("Send Press");
					this.dispatchEvent(new AnsheNetEvent(AnsheNetEvent.LOAD_SWF_PRESS, objLoad));
				}
			}
			catch(err:*)
			{
				// trace("分析文件时出错");
				this.dispatchEvent(new AnsheNetEvent(AnsheNetEvent.LOAD_SWF_ERROR, err));
			}
		}
		
		//	取得已经存在的 SWF 文件的的数据内容
		public function GetSWFByte(sName:String):ByteArray
		{
			for(var i:int = 0; i < swfArray.length; i++)
			{
				var obj:SWFData = swfArray[i];
				if(obj.swfName.toLowerCase().indexOf(sName.toLowerCase()) >= 0)
				{
					return obj.toByteArray();
				}
			}
			return null;
		}
		
		//	从 SWF 数据中取出相应的对象
		private function GetSwfData(sName:String):SWFData
		{
			var sd:SWFData = new SWFData(sName);
			
			for(var i:int = 0; i < swfArray.length; i++)
			{
				var obj:SWFData = swfArray[i];
				if(obj.swfName == sName)
				{
					return obj;
				}
			}
			
			swfArray.push(sd);
			
			return sd;
		}		
		
		//	返回 NC 是否连接标识
		public function get ncConnected():Boolean
		{
			if(this.myNC)
			{
				return this.myNC.connected;
			}
			return false;
		}
		
		//	返回 SO 是否正确连接标识
		public function get soConnedted():Boolean
		{
			return this.mySO.connected;
		}
		
		public function getClass():AnsheNetSpace
		{
			return this;
		}
		
		public function DeleteFunction(funcName:String, func:Function):void
		{
			if(myNC)
			{
				myNC[funcName] = func;
			}
		}

		//--------------------------------------------------------------------------------
		
		//	对象被显示出来后触发事件
		private function InitSpaceData(e:Event):void
		{
			myNC.addEventListener(AnsheNetEvent.SERVER_CONN_COMPLETE, onConnComplete);
			myNC.addEventListener(AnsheNetEvent.SERVER_CONN_ERROR, onConnError);
			myNC.addEventListener(AnsheNetEvent.SERVER_CLOSE, onServerClose);
			
			mySO.addEventListener(AnsheNetEvent.SO_RUSH_DATA, onSoRushData);				
		}		
	
		//	连接成功
		private function onConnComplete(e:AnsheNetEvent):void
		{
			myNC.client = this;
			
			trace("Red5 服务器连接成功", this.space);
			this.stage.dispatchEvent(new AnsheNetEvent(AnsheNetEvent.SERVER_CONN_COMPLETE));
		}

		//	连接出错
		private function onConnError(e:AnsheNetEvent):void
		{
			trace("Red5 服务器连接出错" + e.data);
			this.stage.dispatchEvent(new AnsheNetEvent(AnsheNetEvent.SERVER_CONN_ERROR, e.data));
		}

		//	服务器关闭
		private function onServerClose(e:AnsheNetEvent):void
		{
			trace("Red5 服务器已经断开", this.space);
			this.stage.dispatchEvent(new AnsheNetEvent(AnsheNetEvent.SERVER_CLOSE));
		}

		//	房间 SharedObject 刷新数据
		private function onSoRushData(e:AnsheNetEvent):void
		{
			trace("全局 SharedObject 刷新了数据");
			this.stage.dispatchEvent(new AnsheNetEvent(AnsheNetEvent.SO_RUSH_DATA, e.data));			
		}
	}
}